package models

import (
	"context"
	"math/rand"
	"time"
)

// SignInRecord 签到记录表
type SignInRecord struct {
	Id              int64     `json:"id" xorm:"pk autoincr"`
	UserId          int64     `json:"user_id" xorm:"not null comment('用户ID') index"`
	SignDate        time.Time `json:"sign_date" xorm:"date not null comment('签到日期') index"`
	ContinuousDays  int       `json:"continuous_days" xorm:"not null default 1 comment('连续签到天数')"`
	RedPacketAmount float64   `json:"red_packet_amount" xorm:"decimal(10,2) not null comment('获得红包金额')"`
	UpdateTime      time.Time `json:"update_time" xorm:"not null updated comment('更新时间')"`
	CreateTime      time.Time `json:"create_time" xorm:"not null created comment('创建时间')"`
}

// TableName 表名
func (SignInRecord) TableName() string {
	return "sign_in_record"
}

// SignInRule 签到规则表
type SignInRule struct {
	Id             int64     `json:"id" xorm:"pk autoincr"`
	MinAmount      float64   `json:"min_amount" xorm:"decimal(10,2) not null comment('最小红包金额')"`
	MaxAmount      float64   `json:"max_amount" xorm:"decimal(10,2) not null comment('最大红包金额')"`
	ContinuousDays int       `json:"continuous_days" xorm:"not null default 1 comment('连续签到天数')"`
	ExtraAmount    float64   `json:"extra_amount" xorm:"decimal(10,2) not null default 0 comment('额外奖励金额')"`
	Status         int       `json:"status" xorm:"tinyint(4) not null default 1 comment('状态')"`
	UpdateTime     time.Time `json:"update_time" xorm:"not null updated comment('更新时间')"`
	CreateTime     time.Time `json:"create_time" xorm:"not null created comment('创建时间')"`
}

// TableName 表名
func (SignInRule) TableName() string {
	return "sign_in_rule"
}

// GetTodaySignIn 获取今日签到记录
func GetTodaySignIn(ctx context.Context, userId int64) (*SignInRecord, error) {
	today := time.Now().Format("2006-01-02")
	var record SignInRecord
	exists, err := Get(ctx, &record, "user_id = ? AND sign_date = ?", userId, today)
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, nil
	}
	return &record, nil
}

// GetLastSignIn 获取最后一次签到记录
func GetLastSignIn(ctx context.Context, userId int64) (*SignInRecord, error) {
	var record SignInRecord
	exists, err := getSession(ctx).
		Where("user_id = ?", userId).
		OrderBy("sign_date DESC").
		Limit(1).
		Get(&record)
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, nil
	}
	return &record, nil
}

// GetSignInRule 获取签到规则
func GetSignInRule(ctx context.Context, continuousDays int) (*SignInRule, error) {
	var rule SignInRule
	exists, err := getSession(ctx).
		Where("continuous_days <= ? AND status = ?", continuousDays, 1).
		OrderBy("continuous_days DESC").
		Limit(1).
		Get(&rule)
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, nil
	}
	return &rule, nil
}

// CalculateRedPacketAmount 计算红包金额
func (r *SignInRule) CalculateRedPacketAmount() float64 {
	// 生成随机红包金额
	randAmount := r.MinAmount + rand.Float64()*(r.MaxAmount-r.MinAmount)
	// 保留2位小数
	randAmount = float64(int64(randAmount*100)) / 100
	// 加上额外奖励
	return randAmount + r.ExtraAmount
}

// CreateSignInRecord 创建签到记录
func CreateSignInRecord(ctx context.Context, record *SignInRecord) (err error) {
	ctx = BeginTransaction(ctx)
	defer CloseTransaction(ctx, err)
	// 插入签到记录
	if _, err = Insert(ctx, record); err != nil {

		return err
	}

	// 发放红包
	redPacketRecord := &RedPacketRecord{
		UserId:   record.UserId,
		Type:     RedPacketTypeIncome,
		Amount:   record.RedPacketAmount,
		Source:   RedPacketSourceSign,
		SourceId: "",
		Title:    "签到奖励",
		Remark:   "连续签到" + string(record.ContinuousDays) + "天奖励",
		Status:   RedPacketStatusNormal,
	}

	if err = CreateRedPacketRecord(ctx, redPacketRecord); err != nil {
		return err
	}

	return
}
